﻿using System;
using System.IO;
using System.Text.RegularExpressions;
using DuLabs.Classic.Configuration;
using DuLabs.Classic.Util;

namespace DuLabs.Classic.Logging
{
    public class SingleFileLogWriter : ILogWriter
    {
        // LogWriter参数
        // 必选参数
        // 说明：指定日志文件存放的路径
        private const string PARAM_FILE_PATH = "filePath";

        // LogWriter参数
        // 可选参数
        // 说明：该参数配置为正则表达式，如能匹配则不记录日志（表示关掉指定LogType记录日志的功能）
        private const string PARAM_FILTER = "filter";

        #region ILogger 成员

        public void Write(LogEntry logEntry, ParamElementCollection parameters)
        {
            if (logEntry == null)
            {
                throw new ArgumentNullException("logEntry");
            }

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            // 检查参数
            ParamElement param_filePath = parameters[PARAM_FILE_PATH];
            if (param_filePath == null || string.IsNullOrWhiteSpace(param_filePath.Value))
            {
                throw new ApplicationException(string.Format("Parameter error: {0}", PARAM_FILE_PATH));
            }

            try
            {
                // 检查参数
                ParamElement param_filter = parameters[PARAM_FILTER];
                if (param_filter != null && !string.IsNullOrWhiteSpace(param_filter.Value))
                {
                    Regex regex = new Regex(param_filter.Value, RegexOptions.IgnoreCase);
                    if (regex.IsMatch(logEntry.LogType.ToString()))
                    {
                        return;
                    }
                }

                if (!logEntry.CreateDate.HasValue)
                {
                    logEntry.CreateDate = DateTime.Now;
                }

                if (logEntry.Exception != null)
                {
                    logEntry.Details.Add("Exception.Message : " + logEntry.Exception.Message);
                    logEntry.Details.Add("Exception.StackTrace : " + logEntry.Exception.StackTrace);
                    logEntry.Details.Add("Exception.Source : " + logEntry.Exception.Source);
                }

                string path = param_filePath.Value;

                // 使用日志类型作为子目录
                string dirLogType = logEntry.LogType.ToString();

                // 获取与平台无关的路径分隔符
                string dirSeparatorChar = Path.DirectorySeparatorChar.ToString();

                // 组合日志目录字符串
                path += (path.EndsWith(dirSeparatorChar) ? "" : dirSeparatorChar) + dirLogType + dirSeparatorChar;

                // 检查目录是否存在，不存在则创建
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                // 创建文件名，文件名格式：8位日期-6位时间-GUID前8位-日志类型.xml
                string fileName = string.Format("{0}-{1}-{2}.xml"
                    , DateTime.Now.ToString("yyyyMMdd-HHmmss")
                    , Guid.NewGuid().ToString().Substring(0, 8).ToUpper()
                    , logEntry.LogType.ToString());

                path += fileName;

                // 序列化对象
                XmlSerializationFormat.ToFile(path, logEntry);
            }
            catch
            {
                throw;
            }
        }

        #endregion

    }
}
